home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / lang / Python152_Src.lha / Python152_Source / Amiga / unixemul.c < prev    next >
C/C++ Source or Header  |  1999-04-27  |  7KB  |  356 lines

  1. /**************************************************************\
  2. **                                                            **
  3. **  UNIX 'emulation' functions for AmigaDOS                   **
  4. **                                                            **
  5. **  Made by Irmen de Jong (irmen@bigfoot.com)                 **
  6. **                                                            **
  7. **  21-jan-98: Created. Moved some functions from             **
  8. **             Modules/Amigamodule.c to here.                 **
  9. **  25-dec-98: Added I-Net 225 support                        **
  10. **             Added ftruncate (but not used due to bugs)     **
  11. **                                                            **
  12. **  NOTE: Don't forget __io2errno conversion!!!!!!!!!!!!!!!!  **
  13. **                                                            **
  14. \**************************************************************/
  15.  
  16. #ifndef INET225
  17. #include <dos.h>
  18. #endif
  19. #include <sys/stat.h>
  20. #include <proto/dos.h>
  21. #include <proto/exec.h>
  22. #include <dos/dostags.h>
  23. #include <exec/execbase.h>
  24. #ifdef AMITCP
  25. #include <proto/usergroup.h>
  26. #include <proto/socket.h>
  27. #endif
  28. #ifdef INET225
  29. #include <proto/socket.h>
  30. static int _OSERR;
  31. #endif
  32. #include "Python.h"
  33. #include "protos.h"
  34.  
  35. /************ Utility functions *************/
  36.  
  37. /*** checkLink: check for link loops and other errors ***/
  38. static BOOL checkLink(char *from, BPTR to, BOOL root)
  39. {
  40.     struct FileInfoBlock __aligned fib;
  41.  
  42.     if(Examine(to,&fib))
  43.     {
  44.         if(fib.fib_EntryType>0)
  45.         {
  46.             // directory! Check some things (loops etc)
  47.             char* pp;
  48.             char p;
  49.             BPTR fromLock,temp;
  50.  
  51.             // only superuser may link directories
  52.             if(!root)
  53.             {
  54.                 errno=EPERM; return FALSE;
  55.             }
  56.  
  57.             pp = PathPart(from);
  58.             p = *pp;
  59.             *pp = 0;
  60.             fromLock=Lock(from,SHARED_LOCK);
  61.             *pp=p;
  62.  
  63.             if(fromLock)
  64.             {
  65.                 do {
  66.                     if(SameLock(fromLock,to)==LOCK_SAME)
  67.                     {
  68.                         UnLock(fromLock);
  69.                         errno = ELOOP;
  70.                         return FALSE;       // link loop
  71.                     }
  72.  
  73.                     temp = fromLock;
  74.                     fromLock = ParentDir(fromLock);
  75.                     UnLock(temp);
  76.                 } while (fromLock);
  77.  
  78.                 return TRUE;       // dir, OK.
  79.             }
  80.             else errno=__io2errno(_OSERR=IoErr());
  81.         }
  82.         else return TRUE;      // file, OK.
  83.     }
  84.     else errno=__io2errno(_OSERR=IoErr());
  85.  
  86.     return FALSE;
  87. }
  88.  
  89.  
  90. /************ link(2) : make a hard link ************/
  91.  
  92. /* LINK: make hardlink from 'from' to 'to' (to must exist, from is new) */
  93. /* 'from' may not be a directory if you are not the super-user. */
  94. /* 0=ok, -1=err */
  95. int link(const char *to, const char *from)
  96. {
  97.     BOOL root;
  98.     BPTR toLock;
  99.  
  100.     /* are we superuser? */
  101. #ifdef AMITCP
  102.     if (!checkusergrouplib())
  103. #else
  104.     if (!checksocketlib())
  105. #endif
  106.     {
  107.         PyErr_Clear();
  108.         root=TRUE;  /* can't tell... so be root */
  109.     }
  110.     else if(getuid()==0) root = TRUE;
  111.     else root=FALSE;
  112.  
  113.     if(toLock=Lock(to,SHARED_LOCK))
  114.     {
  115.         if(checkLink(from,toLock,root))
  116.         {
  117.             if(MakeLink(from,(LONG)toLock,FALSE))
  118.             {
  119.                 UnLock(toLock);
  120.                 return 0;
  121.             }
  122.             else errno=__io2errno(_OSERR=IoErr());
  123.         }
  124.         UnLock(toLock);
  125.     }
  126.     else errno=__io2errno(_OSERR=IoErr());
  127.     
  128.     return -1;
  129. }
  130.  
  131. /************** symlink(2): create symbolic (soft) link ********/
  132. int symlink(const char *to, const char *from)
  133. {
  134.     /* symbolic link 'from' is created to 'to' */
  135.     /* 0=ok, else -1 + errno */
  136.  
  137.     BPTR toLock;
  138.  
  139.     if(toLock=Lock(to,SHARED_LOCK))
  140.     {
  141.         if(checkLink(from,toLock,TRUE))
  142.         {
  143.             UnLock(toLock);
  144.             if(MakeLink(from,(LONG)to,TRUE)) return 0;
  145.             else errno=__io2errno(_OSERR=IoErr());
  146.         }
  147.         else UnLock(toLock);
  148.     }
  149.     else errno=__io2errno(_OSERR=IoErr());
  150.     
  151.     return -1;
  152. }
  153.  
  154.  
  155.  
  156. /************** readlink(2): read value of a symbolic link ***********/
  157.  
  158. int readlink(const char *path, char *buf, int bufsiz)
  159. {
  160.     struct MsgPort *port;
  161.     struct stat st;
  162.  
  163.     if(!(port=DeviceProc(path)))
  164.     {
  165.         errno=EIO; return -1;
  166.     }
  167.  
  168.     buf[bufsiz-1]=0;
  169.     errno=0;
  170.  
  171.     if(lstat(path,&st)>=0)
  172.     {
  173.         if(S_ISLNK(st.st_mode))
  174.         {
  175.             char c;
  176.             BPTR dirlock;
  177.             BPTR olddir;
  178.             char *p;
  179.             char *link;
  180.  
  181.             p = PathPart(path);
  182.             link = FilePart(path);
  183.             c = *p; *p='\0';
  184.             dirlock=Lock(path,ACCESS_READ); *p=c;
  185.             if(dirlock)
  186.             {
  187.                 olddir=CurrentDir(dirlock);
  188.  
  189.                 if(!ReadLink(port,dirlock,link,buf,bufsiz))
  190.                     errno=__io2errno(_OSERR=IoErr());
  191.  
  192.                 dirlock=CurrentDir(olddir);
  193.                 UnLock(dirlock);
  194.             }   
  195.             else errno=__io2errno(_OSERR=IoErr());
  196.         }
  197.         else errno=EINVAL;
  198.     }
  199.  
  200.     if(errno!=0) return -1;
  201.  
  202.     if(buf[bufsiz-1]==0) return strlen(buf);
  203.     else return bufsiz;
  204. }
  205.  
  206.  
  207.  
  208. /** custom mkdir() implementation **/
  209. /** This version actually sets protection bits **/
  210. #ifndef INET225
  211. int my_mkdir(const char* path, int p)
  212. {
  213. #ifdef AMITCP
  214.     if(checkusergrouplib()) p &= ~getumask();
  215. #else
  216.     if(checksocketlib()) p &= ~getumask();
  217. #endif
  218.     else PyErr_Clear();
  219.  
  220.     if(0==mkdir(path))
  221.     {
  222.         return chmod(path,p);
  223.     }
  224.     return -1;
  225. }
  226. #endif /* !INET225 */
  227.  
  228. int uname(struct utsname *u)
  229. {
  230.     int res;
  231.  
  232.     strcpy(u->sysname,"AmigaDOS");
  233.     strcpy(u->machine,"m68k");
  234.     if (!checksocketlib())
  235.     {
  236.         char *v;
  237.         PyErr_Clear();
  238.         res=0; v=getenv("HOSTNAME");
  239.         if(v) strcpy(u->nodename, v);
  240.         else strcpy(u->nodename, "localhost");
  241.     }
  242.     else res = gethostname(u->nodename, _UNAME_BUFLEN-1);
  243.     if(res>=0)
  244.     {
  245.         LONG ver_major = SysBase->LibNode.lib_Version;
  246.         LONG ver_minor = SysBase->SoftVer;
  247.         sprintf (u->release, "%d.%d", ver_major,ver_minor);
  248.         if(ver_major<36)
  249.             strcpy(u->version,"1");
  250.         else if(ver_major<39)
  251.             strcpy(u->version,"2");
  252.         else 
  253.             strcpy(u->version,"3");
  254.     }
  255.     return 0;
  256. }
  257.  
  258.  
  259. #ifndef INET225
  260. FILE *popen(const char *command, const char *type)
  261. {
  262.     char file[50];
  263.  
  264.     FILE *fh;
  265.  
  266.     static int num = 1;
  267.  
  268.     if((type[0]!='r') && (type[0]!='w'))
  269.     {
  270.         errno=EINVAL;
  271.         return 0;
  272.     }
  273.         
  274.     sprintf(file,"PIPE:Py_%ld_%ld",num++,FindTask(0));
  275.  
  276.     if(fh=fopen(file,type))
  277.     {
  278.         BPTR fh2;
  279.         LONG mode=MODE_NEWFILE; /* 'r'-peer must write */
  280.  
  281.         if(type[0]=='w') mode=MODE_OLDFILE; /* peer must read */
  282.  
  283.         if(fh2=Open(file,mode))
  284.         {
  285.             BPTR fh3;
  286.             if(type[0]=='r')
  287.             {
  288.                 /* execute command with output to fh */
  289.                 fh3=Open("*",MODE_OLDFILE); /* should use CONSOLE: */
  290.                 if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Output,fh2,
  291.                                     SYS_Input,fh3,TAG_DONE)))
  292.                 {
  293.                     return fh;
  294.                 }
  295.             }
  296.             else /** if(type[0]=='w') **/
  297.             {
  298.                 /* execute command with input from fh */
  299.                 fh3=Open("*",MODE_NEWFILE); /* should use CONSOLE: */
  300.                 if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Input,fh2,
  301.                                     SYS_Output,fh3,TAG_DONE)))
  302.                 {
  303.                     return fh;
  304.                 }
  305.             }
  306.             fclose(fh); Close(fh2); if(fh3) Close(fh3);
  307.             errno=EAGAIN;
  308.             return 0;
  309.         }
  310.         fclose(fh);
  311.     }
  312.     errno=ENOENT;
  313.     return 0;
  314. }
  315.  
  316. int pclose(FILE *stream)
  317. {
  318.     if(stream)
  319.     {
  320.         fclose(stream);
  321.         return 0;
  322.     }
  323.     errno=EINVAL;
  324.     return -1;  
  325. }
  326.  
  327. #endif /* INET225 */
  328.  
  329.  
  330. /*************** ftruncate is not yet used because of bugs in the OS FileSystem :-( ***/
  331.  
  332. #if 0
  333.  
  334. int ftruncate(int fd, long newlength)
  335. {
  336.   struct UFB *ufb;
  337.  
  338.   /*
  339.    * find the ufb *
  340.    */
  341.   if ((ufb = __chkufb(fd)) != NULL && !(ufb->ufbflg & UFB_SOCK))
  342.   {
  343.     if(-1==SetFileSize(ufb->ufbfh,newlength,OFFSET_BEGINNING))
  344.     {
  345.         set_errno(IoErr());
  346.         return -1;
  347.     }
  348.     return 0;
  349.   }
  350.   
  351.   errno = EINVAL;
  352.   return -1;
  353. }
  354.  
  355. #endif
  356.